package com.ytt.core.service.service.major;

import com.ytt.core.model.college.CollegeDto;
import com.ytt.core.model.common.PageDataDTO;
import com.ytt.core.model.major.MajorDto;
import com.ytt.core.model.major.MajorEditDto;
import com.ytt.core.service.entity.college.College;
import com.ytt.core.service.entity.major.Major;
import com.ytt.core.service.exception.NoSuchDataException;
import com.ytt.core.service.mapper.major.MajorMapper;
import com.ytt.core.service.repository.MajorRepository;
import com.ytt.core.service.service.ProposalQueryParam;
import com.ytt.core.service.utils.BaseUtil;
import com.ytt.core.service.utils.PageDataUtil;
import com.ytt.core.util.jpa.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service("majorService")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MajorImpl implements MajorService {

    private  final MajorRepository majorRepository;
    private  final MajorMapper majorMapper;

    @Autowired
    public MajorImpl(MajorRepository majorRepository, MajorMapper majorMapper) {
        this.majorRepository = majorRepository;
        this.majorMapper = majorMapper;
    }

    @Override
    public MajorDto findById(String id) {
        Major notification = this.majorRepository.findById(Long.valueOf(id)).orElseThrow(() -> new NoSuchDataException(id));
        return this.majorMapper.toDTO(notification);
    }

    @Override
    public List<MajorDto> findAll(String sort, ProposalQueryParam param) {
        List<Sort.Order> orders = PageHelper.toSortOrderList(sort);
        Sort sort1 = Sort.by(orders);
        List<Major> notifications = this.majorRepository.findAll(
                BaseUtil.<Major>getBuilder(param).build(), sort1);
        return notifications.stream().map(this.majorMapper::toDTO).collect(Collectors.toList());
    }

    @Override
    public PageDataDTO<MajorDto> findOnePage(Integer page, Integer size, String sort, ProposalQueryParam param) {
        Page<Major> notificationPage = this.majorRepository.findAll(
                BaseUtil.<Major>getBuilder(param).build(), PageHelper.generatePageRequest(page, size, sort));
        List<MajorDto> notificationDTOList = notificationPage.getContent().stream().map(this.majorMapper::toDTO)
                .collect(Collectors.toList());
        return PageDataUtil.toPageData(notificationPage, notificationDTOList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MajorDto create(MajorEditDto saveDTO) {
        Major entity = new Major();
        this.majorMapper.updateEntity(saveDTO, entity);
        entity = this.majorRepository.save(entity);
        return this.majorMapper.toDTO(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MajorDto update(String id, MajorEditDto saveDTO) {
        Optional<Major> optional = this.majorRepository.findById(Long.valueOf(id));
        Major entity = optional.orElseThrow(() -> new NoSuchDataException(id));

        this.majorMapper.updateEntity(saveDTO, entity);
        entity = this.majorRepository.saveAndFlush(entity);
        return this.majorMapper.toDTO(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        Major entity = this.majorRepository.findById(Long.valueOf(id)).orElseThrow(() -> new NoSuchDataException(id));
        this.majorRepository.delete(entity);
    }
}
